﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.ServiceModel;
using WCFServiceWebRole1.Services;
using GlobalObjects;
using System.ServiceModel.Web;
using System.ServiceModel.Description;
using System.Net;
using System.Text;
using System.IO;
using System.Diagnostics;
using WCFServiceWebRole1.DataObjects;
using System.Runtime.Serialization.Json;
using System.Collections.Generic;
using System.Web.Script.Serialization;


namespace IotWebService_Intergration_Test
{
    [TestClass]
    public class DataLoggingTests
    {
        static readonly string DataLoggingServiceBaseAddress = "http://localhost:8090/Services/DataLogging.svc";
        static ServiceHost DataLoggingHost;
        IDataLogging dataLoggingProxy;

        [ClassInitialize]
        public static void ClassInitialize(TestContext context)
        {
            DataLoggingHost = new ServiceHost(typeof(DataLogging));
            DataLoggingHost.AddDefaultEndpoints();
            DataLoggingHost.Open();
        }

        [ClassCleanup]
        public static void ClassCleanup()
        {
            DataLoggingHost.Close();
        }

        [TestInitialize]
        public void Initialize()
        {
            WebChannelFactory<IDataLogging> DataLoggingfactory = new WebChannelFactory<IDataLogging>(new WebHttpBinding(), new Uri(DataLoggingServiceBaseAddress));
            DataLoggingfactory.Endpoint.Behaviors.Add(new WebHttpBehavior());
            dataLoggingProxy = DataLoggingfactory.CreateChannel();
        }

        [TestCleanup]
        public void Cleanup()
        {
            // ((IClientChannel)this.proxy).Close();
        }


        #region Sample
        //[TestMethod]
        //public void TestMethod1()
        //{
        //    //  WebRequest request = WebRequest.Create("http://localhost:8000/Services/users.svc/user/1092");
        //    ////  request.
        //    //  request.Method = "POST";
        //    //  WebResponse ws = request.GetResponse();
        //    //  Encoding enc = System.Text.Encoding.GetEncoding(1252);
        //    //  StreamReader responseStream = new StreamReader(ws.GetResponseStream());
        //    //  string response = responseStream.ReadToEnd();
        //    //  responseStream.Close();
        //    //  Debug.Print(response);


        //    List<Data> data = new List<Data>();
        //    data.Add(new Data() { humidity = 23.01, temperature = 21.90, time = DateTime.UtcNow.ToString() });
        //    TempDataLog dataRequest = new TempDataLog() { sensorId = 2358, deviceId = 1060, firstTime = DateTime.UtcNow.ToString(), lastTime = DateTime.UtcNow.ToString(), data = data };

        //    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("http://localhost:8000/Services/DataLogging.svc/log/1092");
        //    webRequest.Method = "POST";
        //    webRequest.ContentType = "text/json";


        //    //JavaScriptSerializer js2 = new JavaScriptSerializer();
        //    //string jsonData = js2.Serialize(dataRequest);

        //    DataContractJsonSerializer ser = new DataContractJsonSerializer(dataRequest.GetType());

        //    MemoryStream ms = new MemoryStream();
        //    ser.WriteObject(ms, dataRequest);
        //    String json = Encoding.UTF8.GetString(ms.ToArray());
        //    StreamWriter writer = new StreamWriter(webRequest.GetRequestStream());
        //    writer.Write(json);
        //    writer.Close();

        //    //using (System.IO.Stream s = webRequest.GetRequestStream())
        //    //{
        //    //    using (System.IO.StreamWriter sw = new System.IO.StreamWriter(s))
        //    //        sw.Write(jsonData);
        //    //}

        //    //using (System.IO.Stream s = webRequest.GetResponse().GetResponseStream())
        //    //{
        //    //    using (System.IO.StreamReader sr = new System.IO.StreamReader(s))
        //    //    {
        //    //        var jsonResponse = sr.ReadToEnd();
        //    //        System.Diagnostics.Debug.WriteLine(String.Format("Response: {0}", jsonResponse));
        //    //    }
        //    //}

        //    WebResponse ws = webRequest.GetResponse();
        //    Encoding enc = System.Text.Encoding.GetEncoding(1252);
        //    StreamReader responseStream = new StreamReader(ws.GetResponseStream());
        //    string response = responseStream.ReadToEnd();
        //    responseStream.Close();
        //    Debug.Print(response);


        //    //   WebRequest webRequest = WebRequest.Create("http://localhost:8000/Services/users.svc/user/1092");
        //    //   if (webRequest != null)
        //    //   {
        //    //       webRequest.Method = "POST";
        //    //       webRequest.Timeout = 20000;


        //    //       webRequest.ContentType = "application/json; charset=utf-8";
        //    ////       DataContractJsonSerializer ser = new DataContractJsonSerializer(data.GetType());
        //    //       MemoryStream ms = new MemoryStream();
        //    ////       ser.WriteObject(ms, data);
        //    //       String json = Encoding.UTF8.GetString(ms.ToArray());
        //    //       StreamWriter writer = new StreamWriter(webRequest.GetRequestStream());
        //    //       writer.Write(json);
        //    //   }
        //    //using (new OperationContextScope((IContextChannel)proxy))
        //    //{
        //    //    if (WebOperationContext.Current != null)
        //    //        //   WebOperationContext.Current.OutgoingRequest.ContentType = "application/octet-stream";
        //    //        WebOperationContext.Current.OutgoingRequest.Method = "POST";
        //    //   // WebOperationContext.Current.OutgoingRequest.Headers.Add("Authorization","APIKey "
        //    //    Console.WriteLine(proxy.getUserByUserId("1092").response.Username);
        //    //}
        //}

        //[TestMethod]
        //public void TestMethod2()
        //{
        //    // Create the web request 
        //    Uri address = new Uri("http://localhost:8090/Services/DataLogging.svc/log/1092");
        //    HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
        //    request.Method = "POST";
        //    //  request.UseDefaultCredentials = false;
        //    //  request.Credentials = new NetworkCredential(UserName, Password);
        //    //  request.PreAuthenticate = true;
        //    request.ContentType = "application/json";
        //    request.Accept = "application/json";
        //    //        request.Headers.Add("Authorization:APIkey bf9e6201-63a6-4422-a2f4-40e27ce468d4");
        //    //    string data = strinrequest.Headers.Add("Authorization: Basic ZGNpOkFpR2g3YWVj");g.Format("username={0}&password={1}", otherusername, otherpassword);


        //    List<Data> data = new List<Data>();
        //    data.Add(new Data() { humidity = 23.01, temperature = 21.90, time = DateTime.UtcNow.ToString() });
        //    TempDataLog dataRequest = new TempDataLog() { sensorId = 2358, deviceId = 1060, firstTime = DateTime.UtcNow.ToString(), lastTime = DateTime.UtcNow.ToString(), data = data };

        //    JavaScriptSerializer js2 = new JavaScriptSerializer();
        //    string jsonData = js2.Serialize(dataRequest);
        //    // Create a byte array of the data we want to send  
        //    byte[] byteData = UTF8Encoding.UTF8.GetBytes(jsonData);

        //    // Set the content length in the request headers  
        //    request.ContentLength = byteData.Length;

        //    //Write data  
        //    using (Stream postStream = request.GetRequestStream())
        //    {
        //        postStream.Write(byteData, 0, byteData.Length);
        //    }


        //    // Get response
        //    try
        //    {
        //        using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
        //        {
        //            // Get the response stream  
        //            StreamReader reader = new StreamReader(response.GetResponseStream());

        //            // Console application output  
        //            String jsonResponse = reader.ReadToEnd();
        //            Debug.WriteLine(jsonResponse);
        //            reader.Close();
        //        }
        //    }
        //    catch (Exception ex) { }

        //}

        //[TestMethod]
        //public void TestMethod3()
        //{

        //    var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:8090/Services/DataLogging.svc/log/1092");
        //    httpWebRequest.ContentType = "text/json";
        //    httpWebRequest.Method = "POST";

        //    using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
        //    {
        //        List<Data> data = new List<Data>();
        //        data.Add(new Data() { humidity = 23.01, temperature = 21.90, time = DateTime.UtcNow.ToString() });
        //        TempDataLog dataRequest = new TempDataLog() { sensorId = 2358, deviceId = 1060, firstTime = DateTime.UtcNow.ToString(), lastTime = DateTime.UtcNow.ToString(), data = data };

        //        JavaScriptSerializer js2 = new JavaScriptSerializer();
        //        string json = js2.Serialize(dataRequest);

        //        streamWriter.Write(json);
        //        streamWriter.Flush();
        //        streamWriter.Close();
        //    }
        //        var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
        //        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        //        {
        //            var result = streamReader.ReadToEnd();
        //            Debug.WriteLine(result);
        //        }


        //}
        #endregion

        #region dataLogging

        //testing dataLogging Method - Path 1
        [TestMethod]
        [ExpectedException(typeof(WebException), "Raise exception when service returns exception")]
        public void dataLogging_inValid()
        {

            var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:8090/Services/DataLogging.svc/log/1092");
            httpWebRequest.ContentType = "text/json";
            httpWebRequest.Method = "POST";

            using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
            {
                List<Data> data = new List<Data>();
                data.Add(new Data() { humidity = 23.01, temperature = 21.90, time = DateTime.UtcNow.ToString() });
                TempDataLog dataRequest = new TempDataLog() { sensorId = 5361, firstTime = DateTime.UtcNow.ToString(), lastTime = DateTime.UtcNow.ToString(), data = data };

                JavaScriptSerializer js2 = new JavaScriptSerializer();
                string json = js2.Serialize(dataRequest);

                streamWriter.Write(json);
                streamWriter.Flush();
                streamWriter.Close();
            }
            var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                var result = streamReader.ReadToEnd();
                Assert.AreNotEqual("\"Success\"", result.ToString());
               // Debug.WriteLine(result);
            }

        }

        //testing dataLogging Method - Path 2
        [TestMethod]
        public void dataLogging_valid()
        {

            var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:8090/Services/DataLogging.svc/log/1092");
            httpWebRequest.ContentType = "text/json";
            httpWebRequest.Method = "POST";

            using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
            {
                List<Data> data = new List<Data>();
                data.Add(new Data() { humidity = 23.01, temperature = 21.90, time = DateTime.UtcNow.ToString() });
                TempDataLog dataRequest = new TempDataLog() { sensorId = 5361, deviceId = 1060, firstTime = DateTime.UtcNow.ToString(), lastTime = DateTime.UtcNow.ToString(), data = data };

                JavaScriptSerializer js2 = new JavaScriptSerializer();
                string json = js2.Serialize(dataRequest);

                streamWriter.Write(json);
                streamWriter.Flush();
                streamWriter.Close();
            }
            var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                var result = streamReader.ReadToEnd();
                Assert.AreEqual("\"Success\"",result.ToString());
                // Debug.WriteLine(result);
            }

        }

        #endregion

        #region genericDataLogging

        //testing genericDataLogging Method - Path 1
        [TestMethod]
        public void genericDataLogging_valid()
        {

            var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:8090/Services/DataLogging.svc/logData");
            httpWebRequest.Method = "POST";

            using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
            {
                String json = "{\"sensorId\":5361,\"deviceId\":1060,\"firstTime\":\"" + DateTime.UtcNow + "\",\"lastTime\":\"" + DateTime.UtcNow + "\",\"data\": [{\"temperature\":26.649999999999999,\"humidity\":59.630000000000003,\"time\":\"31/07/2011 12:39:31\"},{\"temperature\":26.600000000000001,\"humidity\":59.340000000000003,\"time\":\"31/07/2011 12:39:35\"}]}";
                streamWriter.Write(json);
                streamWriter.Flush();
                streamWriter.Close();
            }
            var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                var result = streamReader.ReadToEnd();
                Assert.AreEqual("\"Success\"", result.ToString());
            }
        }

        //testing genericDataLogging Method - Path 2
        [TestMethod]
        [ExpectedException(typeof(WebException), "Raise exception when service returns exception")]
        public void genericDataLogging_invalid()
        {
            var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:8090/Services/DataLogging.svc/logData");
            httpWebRequest.Method = "POST";

            using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
            {
                String json = "{\"sensorId\":5361,\"firstTime\":\"" + DateTime.UtcNow + "\",\"lastTime\":\"" + DateTime.UtcNow + "\",\"data\": [{\"temperature\":26.649999999999999,\"humidity\":59.630000000000003,\"time\":\"31/07/2011 12:39:31\"},{\"temperature\":26.600000000000001,\"humidity\":59.340000000000003,\"time\":\"31/07/2011 12:39:35\"}]}";
                streamWriter.Write(json);
                streamWriter.Flush();
                streamWriter.Close();
            }
            var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                var result = streamReader.ReadToEnd();
                Assert.AreNotEqual("\"Success\"", result.ToString());
            }
        }

        #endregion

        #region notification 

        //testing notification Method - Path 1
        [TestMethod]
        [ExpectedException(typeof(WebException), "Raise exception when service returns exception")]
        public void notification_inValid_ReasonNull()
        {
            var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:8090/Services/DataLogging.svc/notification");
            httpWebRequest.Method = "POST";

            using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
            {
                Notification notify = new Notification() { sensorId = 5361, deviceId = 1060, userId = 1092 };
                JavaScriptSerializer js2 = new JavaScriptSerializer();
                string json = js2.Serialize(notify);

                streamWriter.Write(json);
                streamWriter.Flush();
                streamWriter.Close();
            }
            var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                var result = streamReader.ReadToEnd();
                Assert.IsNull(result.ToString());
            }
        }

        //testing notification Method - Path 2
        [TestMethod]
        [ExpectedException(typeof(WebException), "Raise exception when service returns exception")]
        public void notification_inValid_deviceIdDoesNotExist()
        {
            var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:8090/Services/DataLogging.svc/notification");
            httpWebRequest.Method = "POST";

            using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
            {
                Notification notify = new Notification() { sensorId=5361, deviceId = 9514, userId = 1092, reason = "lost" };
                JavaScriptSerializer js2 = new JavaScriptSerializer();
                string json = js2.Serialize(notify);

                streamWriter.Write(json);
                streamWriter.Flush();
                streamWriter.Close();
            }
            var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                var result = streamReader.ReadToEnd();
                Assert.IsNull(result.ToString());
            }
        }

        //testing notification Method - Path 3
        [TestMethod]
        [ExpectedException(typeof(WebException), "Raise exception when service returns exception")]
        public void notification_valid()
        {
            var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:8090/Services/DataLogging.svc/notification");
            httpWebRequest.Method = "POST";

            using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
            {
                Notification notify = new Notification() {sensorId=5361, deviceId = 1060, userId = 1092, reason = "lost" };
                JavaScriptSerializer js2 = new JavaScriptSerializer();
                string json = js2.Serialize(notify);

                streamWriter.Write(json);
                streamWriter.Flush();
                streamWriter.Close();
            }
            var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                var result = streamReader.ReadToEnd();
                Assert.IsNull(result.ToString());
            }
        }

        #endregion
    }
}
